# encoding:utf-8

import re
from flask import jsonify, request
import time
from werkzeug.security import generate_password_hash
from werkzeug.utils import redirect
# from apps import config

from apps.blueprint import adog_api
from apps.init_app import mongo
from flask_login import current_user, login_user, logout_user, login_required
from apps.user.process.permissions import permission_required
from apps.user.process.user import User
import xconfig as appc
from threading import Timer
import util.mdbcom as mdbcom
import util.dbcom as dbcom
import util.xtool as xtool
import util.tradeDate as TD
import socket
from flask import Flask, send_from_directory
from flask import request
from flask import render_template
from flask import json
from flask import jsonify
# from flask_socketio import SocketIO, emit, join_room, leave_room, \
#    close_room, rooms, disconnect
import calendar
from datetime import datetime, timedelta
import pandas as pd

global dataMan
import apps.adog.calu as CALU
 
calendar.setfirstweekday(firstweekday=6)
week = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
socketIOInfo = {
              'name_space':appc.name_space,
              'host':appc.host,
              'port':appc.socketIO_port
              }
# Set this variable to "threading", "eventlet" or "gevent" to test the
# different async modes, or leave it set to None for the application to choose
# the best option based on installed packages.
async_mode = None

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
# socketio = SocketIO(app, async_mode=async_mode)


@adog_api.route('/noPermission')
def noPermission():
    return render_template('/adog/noPermission.html')


@adog_api.route('/adog/test', methods=['GET', 'POST'])
def test():
    return render_template('/adog/hello.html')


@adog_api.route('/adog/jqk_alert', methods=['GET', 'POST'])
@login_required
def jqk_alert():
    user = ''
    if current_user.is_authenticated:
        user = str(current_user.username)
    
    folder = appc.jqk_alert_fileName[user].replace('alertlist.txt', '')
    
    # folder=xtool.adogRootPath()+'/apps/templates/file/'
    return send_from_directory(folder.encode('utf-8').decode('utf-8'), 'alertlist.txt', as_attachment=True)


@adog_api.route('/adog/memo', methods=['GET', 'POST'])
@login_required
def memo():
    import apps.adog.memo as MEMO
    user = ''
    if current_user.is_authenticated:
        user = str(current_user.username)
    
    mm = MEMO.Memo(user)
   
    memo_tbl = ''
    att_tbl = ''
    keyPrice_tbl = ''
    display = ''
    att_plot = []
    if request.method == "GET":
        memo = mm.getMemo()
        att = mm.getAtt()
        keyPrice = mm.getKeyPrices()
        memo_tbl = xtool.getHtml(memo, align='left')
        att_tbl = xtool.getHtml(att, align='left')
        keyPrice_tbl = xtool.getHtml(keyPrice, align='left')
        
        att_plot = mm.getAttLast(keyword='', sortBy='att').to_dict('records')   
                            
        return render_template('/adog/memo.html',
                               memo=memo_tbl,
                               att=att_tbl,
                               keyPrice=keyPrice_tbl,
                               att_plot=att_plot)

    elif request.method == "POST":
       
        rs = request.form
        submit_button = rs['submit_button']
        keyword = rs['keyword']
        display = rs['display']
        sortby = rs['sortBy']
        if submit_button == 'select':
            memo = mm.getMemo()
            
            memo = mm.getMemo(keyword=keyword)
            att = mm.getAtt(keyword=keyword)
            keyPrice = mm.getKeyPrices(keyword=keyword)
        
            if display != '':
                if display == 'last_updated':
                    memo.reset_index(drop=False, inplace=True)    
                    memo.drop_duplicates(['chartName', 'symbol', 'interval'], keep='last', inplace=True)
                    
                    att = mm.getAttLast(keyword=keyword, sortBy='att') 
                    
                    keyPrice.reset_index(drop=False, inplace=True)    
                    keyPrice = keyPrice.groupby(by=['chartName', 'symbol'])['text'].apply(list).reset_index()
                    
                elif display == 'all':
                    pass
                
                memo_tbl = xtool.getHtml(memo, align='left')
                att_tbl = xtool.getHtml(att, align='left')
                keyPrice_tbl = xtool.getHtml(keyPrice, align='left')
                
                if sortby != '':
                    att_plot = mm.getAttLast(keyword=keyword, sortBy=sortby).to_dict('records')  
                else:
                    att_plot = mm.getAttLast(keyword=keyword, sortBy='att').to_dict('records') 
           
        return render_template('/adog/memo.html',
                               memo=memo_tbl,
                               att=att_tbl,
                               keyPrice=keyPrice_tbl,
                               att_plot=att_plot)

    
@adog_api.route('/adog/corr', methods=['GET', 'POST'])
@login_required
def corr(): 

    user = ''
    if current_user.is_authenticated:
        user = str(current_user.username)
        
    global cm
    
    selectItems = ''
    if request.method == "GET":
        # plotDiv=cm.drawPlot()
        return render_template('/adog/corr.html',
                               fig='',
                               items=cm.items)

    elif request.method == "POST":
        rs = request.form
        submit_button = rs['submit_button']
        startDate = rs['startDate']
        selectItems = rs.getlist('items')
        if 'all' in selectItems:
            selectItems = []
        if submit_button == 'select':
            cm.setCorr(startDate=startDate, obs=selectItems)
            fig = cm.drawPlot()
            # sns_plot = sns.clustermap(cm.corr) 
            # sns_plot.savefig("sns_corr.png")
        
        return render_template('/adog/corr.html',
                               fig=fig,
                               items=cm.items)
        
  
@adog_api.route('/adog/pattern', methods=['GET', 'POST'])
@login_required
def pattern(): 
    import apps.adog.pattern as PT
    user = ''
    if current_user.is_authenticated:
        user = str(current_user.username)
       
    pattern = mdbcom.find('pattern', outType='pandas')
    pattern['svg'] = ''
    for i in pattern.index:
        if pattern.loc[i, 'cod'] == 'L':
            print(1)
        nodes = pattern.loc[i, 'nodes']
        nodes = json.loads(json.loads(nodes))
        ndf = pd.DataFrame.from_dict(nodes)
        ndf.sort_values(by='x', ascending=1, inplace=True)
        ndf = ndf.tail(10)
        svg_size = [300, 200]  # width=%s height=%s 
        ndf['pv'] = (ndf['close'] / ndf['close'][0] * 200).astype(int)
        ndf['x'] = ndf['x'] - ndf['x'][0]
        nlist = [[ndf.loc[j, 'x'], ndf.loc[j, 'pv']] for j in ndf.index]
        # nlist=nlist+[[nlist[-1][0],200]]
        svg_node = ['%s,%s' % (n[0], n[1]) for n in nlist]
        pattern.loc[i, 'nodes'] = ' '.join(svg_node)
        svg = '<svg width=%s height=%s version="1.1" xmlns="http://www.w3.org/2000/svg">\
            <rect width="%s" height="%s" style="fill:rgb(220,220,220);stroke-width:1;stroke:rgb(0,0,0)"/>\
            <polyline transform="scale(1, -1) translate(0, -%s)" points="%s" \
            style="fill:none;stroke:red;stroke-width:2"/></svg>' % (
                                                                  svg_size[0],
                                                                  svg_size[1],
                                                                  svg_size[0],
                                                                  svg_size[1],
                                                                  # int(svg_size[0]/len(ndf['x'])),#scale
                                                                  # int(svg_size[1]/max(ndf['pv'])), 
                                                                  svg_size[0],
                                                                      
                                                             ' '.join(svg_node)
                                                             )

        pattern.loc[i, 'svg'] = svg
   
    if request.method == "GET":
        pattern.reset_index(drop=True, inplace=True)   
        tbl = xtool.getHtmlTable(pattern, \
                                border='1', \
                                width='95%', \
                                tbody_align='left', \
                                hasIndexCheckBox=False, \
                                # inputHiddenKeyField='_id',
                                exlusiveField=['_id'])
        return render_template('/adog/pattern.html', tbl=tbl)
    elif request.method == "POST":
        rs = request.form
        submit_button = rs['submit_button']
        keyword = rs['keyword']
        sortby = rs['sortBy']
        if submit_button == 'select':
            if keyword != '':
                pattern = pattern.loc[pattern['cod'].str.contains(keyword, case=False),:]
            pt = PT.Pattern()
            pt.loadData(dataMan, startDate='2020-01-01')
            keyItems = pt.fi.loc[pt.fi[u'重点关注'] == '1', u'首码']
            pattern = pd.DataFrame([], columns=['cod', 'freq', 'nodes'])
            for k in keyItems:
                d = pt.data.loc[pt.data['cod'] == k, ['date', 'close']]
                d.sort_values(by='date', ascending=1, inplace=True)
                d.reset_index(drop=True, inplace=True)
                smooth_data = pt.smooth(d['close'], 5)
                # plt.plot(smooth_data)
            
                p = pt.find_peak_triangleNum(smooth_data, 10)
                nodes = pt.getPeakValley(d, p)
                dfn = pd.DataFrame([[k, '1d', nodes]], columns=['cod', 'freq', 'nodes'])
                
                pattern = pattern.append(dfn)
                print(p)
            pattern['_id'] = pattern['cod'] + '_' + pattern['freq']
            pattern['xtime'] = xtool.nowTime()
            mdbcom.saveBatch('pattern', pattern.to_dict(orient='records'))
                 
            pattern.reset_index(drop=True, inplace=True)   
            
        elif submit_button == 'save':
            for k, v in rs.items():
                if 'txtarea' in k:
                    v = rs[k]
                    if v != u'':
                        memo_df.loc[memo_df['_id'] == k[8:], 'followup'] = v
            mdbcom.saveBatch('tv_memo', memo_df.to_dict('records'))
            dbcom.creatTableReplaceMany('tv_memo', memo_df, drop_exist=False)
            
        memo = xtool.getHtmlTable(memo_df, \
                                    border='1', \
                                    width='95%', \
                                    tbody_align='left', \
                                    hasIndexCheckBox=False, \
                                    # inputHiddenKeyField='',
                                    exlusiveField=['_id', 'user'],
                                    key=['_id'],
                                    textAreaFiled=['followup'])
        return render_template('/adog/memo.html',
                       text_all=memo)
   

@adog_api.route('/adog/relation', methods=['GET', 'POST'])
@login_required
def relation():
    import apps.adog.relation as REL
    
    user = ''
    if current_user.is_authenticated:
        user = str(current_user.username)
    
    log = ''
    endDate = xtool.nowDate()
    startDate = TD.tradeDateBefAftX(endDate, -7)
    tradeDate = TD.tradeDateDf
    tradeDate = tradeDate.loc[(tradeDate['tradeDate'] >= startDate) & (tradeDate['tradeDate'] <= endDate)]
    tradeDate.reset_index(drop=True, inplace=True)
    tradeDate = tradeDate['tradeDate'].tolist()
    
    if request.method == "GET":
        r = REL.Relation(is15minToday=True, vs_info='realtime(vs prev day)', obs_exclusive=['T', 'TF', 'TS', 'BB'])
        nds = r.getNodes()
        nodes = nds[-1][1]  # ,time='11:00')
        log = nds[-1][0]
        edges = r.getEdges()
        combos = r.getCombos()
        hulls = r.getHulls()
        
        '''
        [
               dict(size=40, id='A', label='\u8c46\u4e00\u671f\u8d27\u6307\u6570A')
               ]
        '''
        return render_template('/adog/relation.html',
                               log=log,
                               nodes=nodes,
                               edges=edges,
                               hulls=hulls,
                               combos=combos,
                               tradeDate=tradeDate)
        
    elif request.method == "POST":
        rs = request.form
        submit_button = rs['submit_button']
        td = rs['tradeDate']
      
        if submit_button == 'select':
            if td != '':
                r = None
                if 'realtime' in td:
                    r = REL.Relation(is15minToday=True, vs_info=td, obs_exclusive=['T', 'TF', 'TS', 'BB'])
                elif '--' in td:
                    pass
                else:
                    r = REL.Relation(tradeDate=[td], freq='1d', obs_exclusive=['T', 'TF', 'TS', 'BB'])
                nds = r.getNodes()
                nodes = nds[-1][1]  # ,time='11:00')
                log = nds[-1][0]
                edges = r.getEdges()
                combos = r.getCombos()
                hulls = r.getHulls()
        return render_template('/adog/relation.html',
                               log=log,
                               nodes=nodes,
                               edges=edges,
                               hulls=hulls,
                               combos=combos,
                               tradeDate=tradeDate)
  
        
@adog_api.route('/adog/hv', methods=['GET', 'POST'])
def hv():
    fi = dbcom.select_tuple_dict('select *, 同列 as "blk_cn" from future_info where 备注="Q" order by _id')
    future_info = pd.DataFrame.from_records(fi)
    future_info['broker'] = [future_info.loc[i, 'broker_ID']\
                           .replace(u'CFES', 'CCFX')\
                           .replace(u'CZC', 'XZCE')\
                           .replace(u'DCE', 'XDCE')\
                           .replace(u'SHF', 'XSGE')\
                           .replace(u'INE', 'XINE') for i in future_info.index]
    cod_cn = ['%s_%s_%s' % (future_info.loc[i, '首码'], future_info.loc[i, '品种_df'], future_info.loc[i, 'broker']) for i in future_info.index] 
    
    select_cod = ''
    hv_type = ''
    select_hv_type = ''
    hv_div = ''
    
    if request.method == "GET":
        return render_template('/adog/hv.html',
                               cod_cn=cod_cn,
                               select_cod=select_cod,
                               hv_type=hv_type,
                               select_hv_type=select_hv_type,
                               hv_div=hv_div,
                               )
        
    elif request.method == "POST":
        rs = request.form
        submit_button = rs['submit_button']
        if submit_button == 'select': 
            cods = rs.getlist('cod')
            select_cod = [c.split('_')[0] for c in cods]
            select_hv_type = rs.getlist('hv_type')
            if len(select_hv_type) == 0 or 'all' in select_hv_type:
                select_hv_type = ['hv1W', 'hv2W', 'hv1M', 'hv2M', 'hv3W', 'hv6M', 'hv1Y'] 
                
        all = None
        endDate = xtool.nowDate()
        if xtool.nowOnlyTimeMins() > '20:55':
            endDate = TD.tradeDateBefAftX(endDate, +1) 
        
        if 'all' in select_cod:
            for i in future_info.index:
                cod = future_info.loc[i, '_id']
                caluObj = CALU.Calu(cod=cod)
                hv = caluObj.getHistVolatilityYangZhang(cod=cod, beginDate='2019-01-01', endDate=endDate)        
                if all is None:
                    all = hv
                else:
                    all = all.append(hv)
        else:
            for cod in select_cod: 
                caluObj = CALU.Calu(cod=cod)
                hv = caluObj.getHistVolatilityYangZhang(cod=cod, beginDate='2019-01-01', endDate=endDate)        
                if all is None:
                    all = hv
                else:
                    all = all.append(hv)  
        if (not all is None) and (len(all) > 0): 
            all.reset_index(drop=True, inplace=True)            
            all['cod_cn'] = ['%s_%s_%s' % (all.loc[i, 'cod'], all.loc[i, 'code_cn'].replace('期货指数', ''), all.loc[i, 'broker']) for i in all.index] 
            
            hvt = [h for h in  select_hv_type if 'hv' in h]
            all = all.loc[:, ['date', 'cod_cn'] + hvt]
            
            hv_div = caluObj.drawHv(all)        
        return render_template('/adog/hv.html',
                               cod_cn=cod_cn,
                               select_cod=select_cod,
                               hv_type=hv_type,
                               hv_div=hv_div,
                             
                               )


@adog_api.route('/adog/signal', methods=['GET', 'POST'])
@login_required       
def signal():
    return render_template('/adog/signal.html')
    
    
@adog_api.route('/adog/pattern_tracking', methods=['GET', 'POST'])
@login_required       
def pattern_tracking():
    import apps.adog.fthq as FT
    div1 = ''
    div2 = ''
    div3_c = ''
    div3_p = ''
    div4 = ''
    select_blks = []
    isQQ = 'Q'
    pre_weeks = 16
    select_pre_weeks = ''
    select_obs = 'volume'
    isAllCloseStartZero = 'no'
    
    if request.method == "GET":
        ft = FT.FTHQ()
        ft.loadData(cods=[], exlusive_blk=['其他', '股债'], pre_weeks=pre_weeks, isAllCloseStartZero='no')
        blks = ft.future_info['blk'].unique().tolist()    
        dx = ft.pivot_data.copy()
        # dx_all=dx.mean()
        div1 = ft.plot(dx, type='all', select_obs='volume')
        div2 = ft.plot(dx, type='blk', select_obs='volume')
        
        return render_template('/adog/pattern_tracking.html',
                               div1=div1,
                               div2=div2,
                               div3_c=div3_c,
                               div3_p=div3_p,
                               div4=div4,
                               
                               blks=blks,
                               select_blks=select_blks,
                               select_pre_weeks=select_pre_weeks,
                               select_obs=select_obs
                               )
        
    elif request.method == "POST": 
        rs = request.form
        submit_button = rs['submit_button']
        if submit_button == 'select': 
            select_blks = rs.getlist('blks')
            select_pre_weeks = rs['pre_weeks']
            select_obs = rs['obs']   
            if select_obs == '成交量':
                select_obs = 'volume'
            elif select_obs == '持仓量':
                select_obs = 'openInt'
            elif select_obs == '比前日收盘':
                select_obs = 'chg_cls_r'
            else:
                select_obs = 'volume'
            isQQ = rs['isQQ']
            isAllCloseStartZero = rs['isAllCloseStartZero']
            
            ft = FT.FTHQ()
            blks = None
            dx = None
            if select_pre_weeks is not None and select_pre_weeks != '':
                ft.loadData(cods=[], exlusive_blk=['其他', '股债'], pre_weeks=int(select_pre_weeks), isAllCloseStartZero=isAllCloseStartZero)
                blks = ft.future_info['blk'].unique().tolist()
                dx = ft.pivot_data.copy()
            
            div1 = ft.plot(dx, type='all', select_obs=select_obs, div_id='d1')
            div2 = ft.plot(dx, type='blk', select_obs=select_obs, div_id='d2')
            
            if select_blks == [] or 'all' in select_blks:
                select_blks = blks
            
            ds = None
            if isQQ == 'Q':
                ds = dx.query('(blk in %s) and (isQQ=="%s")' % (select_blks, isQQ))
            else:
                ds = dx.query('blk in %s' % (select_blks))
            
            div3_c = ft.plot(ds, type='select_blks', select_blks=select_blks, select_obs=select_obs, div_id='div3_c')
            div3_p = ft.plot(ds, type='select_blks', select_blks=select_blks, select_obs=select_obs, div_id='div3_p', isReverseZaxis=True)
            div4 = ft.plot(ds, type='select_items', select_blks=select_blks, select_obs=select_obs, width=2000, height=1000)
            # div5=ft.plot(ds,type='select_items',select_blks=select_blks,select_obs=select_obs,isQQ='')
        
        return render_template('/adog/pattern_tracking.html',
                               div1=div1,
                               div2=div2,
                               div3_c=div3_c,
                               div3_p=div3_p,
                               div4=div4,
                               
                               blks=blks,
                               select_blks=select_blks,
                               select_pre_weeks=select_pre_weeks,
                               select_obs=select_obs
                             )   


@adog_api.route('/adog/testPattern', methods=['GET', 'POST'])    
def testPattern():
    import apps.adog.fthq as FT
    div1 = ''
    div2 = ''
    div3 = ''
    div4 = ''
    select_blks = []
    isQQ = 'Q'
    pre_weeks = 1
    select_pre_weeks = ''
    select_obs = 'volume'
    isAllCloseStartZero = 'no'
    
    if request.method == "GET":
        ft = FT.FTHQ()
        ft.loadData(cods=['A', 'AU'], exlusive_blk=['ÆäËû', '¹ÉÕ®'], pre_weeks=pre_weeks, isAllCloseStartZero='no')
        blks = ft.future_info['blk'].unique().tolist()    
        dx = ft.pivot_data.copy()
        # dx_all=dx.mean()
        div1 = ft.plot(dx, type='all', select_obs='volume')
        # div2=ft.plot(dx,type='blk',select_obs='volume')
        
        return render_template('/adog/testPattern.html',
                               div1=div1,
                           
                               )
        
    elif request.method == "POST": 
        
        return render_template('/adog/pattern_tracking.html',
                               div1=div1,
                               div2=div2,
                               div3=div3,
                               div4=div4,
                               blks=blks,
                               select_blks=select_blks,
                               select_pre_weeks=select_pre_weeks,
                               select_obs=select_obs
                             )   
        
        
@adog_api.route('/adog/backTrader', methods=['GET', 'POST'])
@login_required       
def pv():
    import apps.adog.backTrader as bt
    div = ''
    user = ''
    if current_user == 'xf':
        user = '0161213030587'
    if request.method == "GET":
        bt = bt.BackTrader(user=user, startDate='2018-12-01', initCap=4000)
        bt.loadStrategyDeal(code='SC8888')
        bt.eval()
        div = bt.plot2()
        
        return render_template('/adog/backTrader.html',
                               div=div  
                               )
        
    elif request.method == "POST": 
        rs = request.form
        submit_button = rs['submit_button']
        if submit_button == 'select': 
            startDate = rs['startDate']
            initCap = int(rs['initCap'])
            code = rs['code']
            handsUnit = int(rs['handsUnit'])
            bt = bt.BackTrader(user=user, startDate=startDate, initCap=initCap)
            bt.loadStrategyDeal(code=code, handsUnit=handsUnit)
            bt.eval()
            div = bt.plot2()
            
        return render_template('/adog/backTrader.html',
                               div=div
                             )  
        
